<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------

// 应用公共文件

function endoceArr($arr){
    return json_decode(json_encode($arr),true);   
}

/**
 * 用户密码加密
 * @param  [string] $pwd [用户密码]
 * @return [type]      [description]
 */
function createPwd($pwd){
    $pwd = md5(config('YOUNG_USER_PASKEY').$pwd);
    return $pwd;
}

/**
 * 检验邮箱
 * @param [string] $email [邮箱]
 * @return [bool]   $reluse  [true false]
 */
function checkEmail($email){
    $check = "/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/";
    $reluse = preg_match($check,$email);

    return $reluse;
}

/**
 * 检验手机号正则
 * @param  [string] $tel [手机号]
 * @return [bool]   $reluse  [true false]
 */
function checkTel($tel){
    $check = "/^1[0-9]{10}$/";
    $reluse = preg_match($check,$tel);
    return $reluse;
}




/**
 * 发送邮件
 * @param  string $address 需要发送的邮箱地址 发送给多个地址需要写成数组形式
 * @param  string $subject 标题
 * @param  string $content 内容
 * @return boolean       是否成功
 */
function sendEmail($address,$subject,$content){

    $email_smtp=config('EMAIL_SMTP');
    $email_username=config('EMAIL_USERNAME');
    $email_password=config('EMAIL_PASSWORD');
    $email_from_name=config('EMAIL_FROM_NAME');

    if(empty($email_smtp) || empty($email_username) || empty($email_password) || empty($email_from_name)){
        return ["error"=>1,"message"=>'邮箱配置不完整'];
    }
    vendor('PHPMailer.Phpmailer');
    vendor('PHPMailer.class#smtp');//注意：点号引入用#代替
    $phpmailer=new \Phpmailer();
    // 设置PHPMailer使用SMTP服务器发送Email
    $phpmailer->IsSMTP();
    // 设置为html格式
    $phpmailer->IsHTML(true);
    // 设置邮件的字符编码'
    $phpmailer->CharSet='UTF-8';
    // 设置SMTP服务器。
    $phpmailer->Host=$email_smtp;
    // 设置为"需要验证"
    $phpmailer->SMTPAuth=true;
    // 设置用户名
    $phpmailer->Username=$email_username;
    // 设置密码
    $phpmailer->Password=$email_password;
    // 设置邮件头的From字段。
    $phpmailer->From=$email_username;
    // 设置发件人名字
    $phpmailer->FromName=$email_from_name;
    // 添加收件人地址，可以多次使用来添加多个收件人

    if(is_array($address)){
        foreach($address as $addressv){
            $phpmailer->AddAddress($addressv);
        }
    }else{
        $phpmailer->AddAddress($address);
    }

    // 设置邮件标题
    $phpmailer->Subject=$subject;
    // 设置邮件正文
    $phpmailer->Body=$content;
    // 发送邮件。

    if(!$phpmailer->Send()) {
        $phpmailererror=$phpmailer->ErrorInfo;
        return array("error"=>1,"message"=>$phpmailererror);
    }else{
        return array("error"=>0);
    }
}

/**
 * 发送短信验证码
 * @param  [string] $tel  [接收 手机号]
 * @param  [string] $code [验证码]
 * @param  [string] $type [true:注册模板    false:身份验证模板]
 * @return [type]       [true:成功 false:失败]
 */
function send_sms($tel,$code,$type=false){
    Vendor('Sms.TopSdk');

    $appkey = config("SMS_APPKEY");
    $secret = config("SMS_SECRET");
    $SignName = config("SMS_SIGNNAME");
    $product = config("SMS_PRODUCT");

    if($type){
        $smsmodelid = config("SMS_REGISTER_MODELID");
    }else{
        $smsmodelid = config("SMS_STATUS_MODELID");
    }

    $c = new \TopClient;
    $c->appkey = $appkey;
    $c->secretKey = $secret;
    $req = new \AlibabaAliqinFcSmsNumSendRequest;
    $req->setSmsType("normal");
    $req->setSmsFreeSignName($SignName);
    $req->setSmsParam("{\"code\":\"$code\",\"product\":\"$product\"}");
    $req->setRecNum($tel);
    $req->setSmsTemplateCode($smsmodelid);
    $resp = $c->execute($req);
    
    $return = object_to_array($resp);

    if(isset($return["sub_code"])){
        return false;
    }else{
        return true;
    }
}

/**
 * 字符串截取，支持中文和其他编码
 * @param string $str 需要转换的字符串
 * @param string $start 开始位置
 * @param string $length 截取长度
 * @param string $charset 编码格式
 * @param string $suffix 截断显示字符
 * @return string
 */
function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=true){
    $len = strlen($str);
    if(function_exists("mb_substr")){
        if($suffix)
            return mb_substr($str, $start, $length, $charset);
        else
            return mb_substr($str, $start, $length, $charset);
    }
    elseif(function_exists('iconv_substr')) {
        if($suffix && $len>$length)
            return iconv_substr($str,$start,$length,$charset);
        else
            return iconv_substr($str,$start,$length,$charset);
    }
    $re['utf-8']   = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
    $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
    $re['gbk']    = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
    $re['big5']   = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
    preg_match_all($re[$charset], $str, $match);
    $slice = join("",array_slice($match[0], $start, $length));
    if($suffix) return $slice;
    return $slice;
}

/**
 * 获取文件名的扩展名
 * @param string $fileName 文件名
 * @return string 扩展名
 */
function getExt($fileName){
    return pathinfo($fileName,PATHINFO_EXTENSION);
}

/**
 * 下载(支持图片)
 * @param  [string] $path_name [文件路径]
 */
function download_by_path($path_name){

     ob_end_clean();

     $len = strrpos($path_name,"/");
     $save_name = substr($path_name,$len+1);

     $hfile = fopen($path_name, "rb") or die("Can not find file: $path_name\n");

     Header("Content-type: application/octet-stream");

     Header("Content-Transfer-Encoding: binary");

     Header("Accept-Ranges: bytes");

     Header("Content-Length: ".filesize($path_name));

     Header("Content-Disposition: attachment; filename=\"$save_name\"");

     while (!feof($hfile)) {

        echo fread($hfile, 32768);

     }

     fclose($hfile);

}

/**
 * 同一张图片生成条形码和二维码
 * @param [string] text 条形码字符串
 * @param [string] qrtest 二维码字符串
 * @param [boolean] type 类型:true浏览器下载二维码,false页面查看图片
 * @return [string] filepath 下载图片路径，false就直接输出图片内容
 */
 
function barQrCode($text, $qrtext, $type, $path=''){
    $size = 30; //条形码高度
    $orientation = 'horizontal';
    $print = true;
    $sizefactor = 1;
    $SizeFactor=2;
    
    $code_string = "";
    // Translate the $text into barcode the correct $code_type
    $chksum = 104;
    // Must not change order of array elements as the checksum depends on the array's key to validate final code
    $code_array = array(" "=>"212222","!"=>"222122","\""=>"222221","#"=>"121223","$"=>"121322","%"=>"131222","&"=>"122213","'"=>"122312","("=>"132212",")"=>"221213","*"=>"221312","+"=>"231212",","=>"112232","-"=>"122132","."=>"122231","/"=>"113222","0"=>"123122","1"=>"123221","2"=>"223211","3"=>"221132","4"=>"221231","5"=>"213212","6"=>"223112","7"=>"312131","8"=>"311222","9"=>"321122",":"=>"321221",";"=>"312212","<"=>"322112","="=>"322211",">"=>"212123","?"=>"212321","@"=>"232121","A"=>"111323","B"=>"131123","C"=>"131321","D"=>"112313","E"=>"132113","F"=>"132311","G"=>"211313","H"=>"231113","I"=>"231311","J"=>"112133","K"=>"112331","L"=>"132131","M"=>"113123","N"=>"113321","O"=>"133121","P"=>"313121","Q"=>"211331","R"=>"231131","S"=>"213113","T"=>"213311","U"=>"213131","V"=>"311123","W"=>"311321","X"=>"331121","Y"=>"312113","Z"=>"312311","["=>"332111","\\"=>"314111","]"=>"221411","^"=>"431111","_"=>"111224","\`"=>"111422","a"=>"121124","b"=>"121421","c"=>"141122","d"=>"141221","e"=>"112214","f"=>"112412","g"=>"122114","h"=>"122411","i"=>"142112","j"=>"142211","k"=>"241211","l"=>"221114","m"=>"413111","n"=>"241112","o"=>"134111","p"=>"111242","q"=>"121142","r"=>"121241","s"=>"114212","t"=>"124112","u"=>"124211","v"=>"411212","w"=>"421112","x"=>"421211","y"=>"212141","z"=>"214121","{"=>"412121","|"=>"111143","}"=>"111341","~"=>"131141","DEL"=>"114113","FNC 3"=>"114311","FNC 2"=>"411113","SHIFT"=>"411311","CODE C"=>"113141","FNC 4"=>"114131","CODE A"=>"311141","FNC 1"=>"411131","Start A"=>"211412","Start B"=>"211214","Start C"=>"211232","Stop"=>"2331112");
    $code_keys = array_keys($code_array);
    $code_values = array_flip($code_keys);
    for ( $X = 1; $X <= strlen($text); $X++ ) {
        $activeKey = substr( $text, ($X-1), 1);
        $code_string .= $code_array[$activeKey];
        $chksum=($chksum + ($code_values[$activeKey] * $X));
    }
    $code_string .= $code_array[$code_keys[($chksum - (intval($chksum / 103) * 103))]];
    $code_string = "211214" . $code_string . "2331112";
    
    // Pad the edges of the barcode
    $code_length = 30;
    
    $text_height = 30;
    
    
    for ( $i=1; $i <= strlen($code_string); $i++ ){
        $code_length = $code_length + (integer)(substr($code_string,($i-1),1));
    }
    if ( strtolower($orientation) == "horizontal" ) {
        $img_width = $code_length*$SizeFactor;
        $img_height = $size;
    } else {
        $img_width = $size;
        $img_height = $code_length*$SizeFactor;
    }
    
    //创建条形码
    $image = imagecreate(300, 300);
    $black = imagecolorallocate ($image, 0, 0, 0);
    $white = imagecolorallocate ($image, 255, 255, 255);
    imagefill( $image, 0, 0, $white );
    
    //linux mydeihui.com 
    //imagefttext($image, 9, 0, 45, 35, imagecolorallocate($image, 0, 0, 0), '/usr/share/fonts/dejavu/simhei.ttf', mb_convert_encoding('服务号:'.$text,'html-entities','UTF-8'));
    
    //win7
    //imagefttext($image, 14, 0, 40, 35, imagecolorallocate($image, 0, 0, 0), 'simhei.ttf', mb_convert_encoding('服务号:'.$text,'html-entities','UTF-8'));

    //swaylink.cn  linux
    imagefttext($image, 14, 0, 88, 60, imagecolorallocate($image, 0, 0, 0), '/usr/share/fonts/liberation/simhei.ttf', mb_convert_encoding('服务号:'.$text,'html-entities','UTF-8'));
    
    $location = 25;
    for ( $position = 1 ; $position <= strlen($code_string); $position++ ) {
        $cur_size = $location + ( substr($code_string, ($position-1), 1) );
        imagefilledrectangle( $image, $location*$SizeFactor, 0, $cur_size*$SizeFactor, $img_height, ($position % 2 == 0 ? $white : $black));
        $location = $cur_size;
    }
    
    
    $back = imagecreate(323, 446);
    imagecopy($back, $image, 0, 0, 0, 0, 300, 200);
    ImageDestroy($image);

    vendor('phpqrcode.phpqrcode');
    $QRencode = new \QRencode();
    $frame = $QRencode->encode($qrtext);
    $pixelPerPoint = 7;
    $outerFrame = 1;
    
    $h = count($frame);
    $w = strlen($frame[0]);
    
    $imgW = $w + 2*$outerFrame;
    $imgH = $h + 2*$outerFrame;
    
    //创建背景
    $base_image =ImageCreate($imgW, $imgH);
    
    $col[0] = ImageColorAllocate($base_image,255,255,255);
    $col[1] = ImageColorAllocate($base_image,0,0,0);    
    
    imagefill($base_image, 0, 0, $col[0]);
    
    for($y=0; $y<$h; $y++) {
        for($x=0; $x<$w; $x++) {
            if ($frame[$y][$x] == '1') {
                ImageSetPixel($base_image,$x+$outerFrame,$y+$outerFrame,$col[1]);
            }
        }
    }
    
    //生成二维码
    $target_image = ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint);
    
    ImageCopyResized($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH);
    ImageDestroy($base_image);
    imagecopy($back, $target_image, 15, 75, 0, 0, 270, 270);
    ImageDestroy($target_image);
    
    
    switch ($type) {
        case 2:
            header ('Content-type: image/png');
            imagepng($back);
        break;
        
        case 1:
            header ('Content-type: image/png');
            Header("Content-type: application/octet-stream");
            Header("Accept-Ranges: bytes");
            Header("Accept-Length:".$file_size);
            Header("Content-Disposition: attachment; filename=$text".'.png');
            ob_clean();
            imagepng($back);
        break;
        case 3:
//             imagepng($back, 'test.png');
            imagepng($back, $path.'/'.$text.'.png');
        break;
    }
    
    imagedestroy($back);
}



/**
 * json数据传输
 * @param int $status 状态
 * @param string $message 提示信息
 * @param array $data 数据
 * @return string json数据
 */
function  show($status, $message,$data=array()) {
    $result = array(
        'status' => $status,
        'message' => $message,
        'data' => $data,
    );
    exit(json_encode($result));
}


/**
 * 按pid递归(树形结构)
 * @param  array  $data   需要递归的数组
 * @param  integer $pid    父级id
 * @return array          树形结构的数组
 */
function tree($data, $pid = 0) {
    $arr = array();

    foreach ($data as $item) {
        if ($item->pid == $pid) {
            $item->child = tree($data, $item->id);
            $arr[] = $item;
        }
    }

    return $arr;
}

/**
 * 按pid递归(树形结构)
 * @param  array  $data   需要递归的数组
 * @param  integer $pid    父级id
 * @return array          树形结构的数组
 */
function eltree($data, $pid = 0) {
    $arr = array();

    foreach ($data as $item) {
        if ($item->pid == $pid) {
            $item->children = eltree($data, $item->id);
            $arr[] = $item;
        }
    }

    return $arr;
}

/**
 * 上传文件
 * @param string upName 上传文件名
 * @param string saveName 保存文件名，传空则根据时间自动命名，不需要后缀名
 * @param string path 保存文件夹路径
 * @param string size 文件大小上限，单位:M
 * @return array 上传成功返回文件路径,上传失败，返回失败信息
 * */
function uploadFile($upName, $saveName='', $path='/uploads/', $size=5){
	if(!isset($_FILES[$upName])) return ['state' => 0, 'msg' => '请上传文件'];

	if($_FILES[$upName]['error'] != 0) return ['state' => 0, 'msg' => '文件上传失败,请重试!'];

	if($_FILES[$upName]['size'] > $size*1024*1024) return ['state' => 0, 'msg' => "文件大小不能超过{$size}M"];
	
	$temp = explode('.', microtime(true));
	if(!$saveName) $saveName = $temp[0].$temp[1];
	$ext = getExt($_FILES[$upName]['name']);

	if(!move_uploaded_file($_FILES[$upName]['tmp_name'], '.'.$path.$saveName.'.'.$ext)) 
		return ['state' => 0, 'msg' => '文件上传失败,请重试!'];
	
	return ['state' => 1, 'msg' => $path.$saveName.'.'.$ext];
}

/**
 * 返回当前时刻，时区$tz当天开始和结束时间戳
 * @param  [string] $tz [东时区，$tz为[0,12]间整数；西时区，为负整数]
 * @return [array]  $data  [st-当天开始时间戳；et-当天结束时间戳]
 */
function get_today_start_and_end_timestamp_on_the_timezone($tz){

    $now = time();

    $st = $now - $now%86400 - $tz*3600;

    $et = $st + 86400;

    $data["st"] = $st;
    $data["et"] = $et;

    return $data;
}


/**
 * 图片上传
 * @param   string $file 文件名
 * @param   string $name 文件模块
 * @return mixed
 */
function upload($file,$name)
{
    $file = request()->file($file);
    if ($file){
        $path = ROOT_PATH . 'public' . DS . 'uploads';
        if (is_array($file) && !empty($file)){
            $fName=[];
            foreach ($file as $f){
                $fileName = $name. DS .time().rand(1,999);
                $info=$f->move($path,$fileName);
                $fName[]=$info->getSaveName();
            }
            return $fName;
        }
        $fileName = $name. DS .time().rand(1,999);
        $info = $file->move($path,$fileName);
        return $info->getSaveName();
    }
    return '';
}


/**
 * 获取时间戳到毫秒
 * @return [string] $times [到毫秒]
 */
function getTimes(){
    
    list($usec, $sec) = explode(" ", microtime());
 
    $times = ((float)$usec + (float)$sec);
    return $times;
}

/**
 * 几分钟前/几小时前、几天前
 * @param  [type] $time [UTC时间戳]
 * @return [type]       [description]
 */
function tranTime($time) {
    $rtime = date("m-d H:i",$time);
    $htime = date("H:i",$time);
    $time = time() - $time;
    if ($time < 60) {
        $str = '刚刚';
    }elseif ($time < 60 * 60) {
        $min = floor($time/60);
        $str = $min.'分钟前';
    }elseif ($time < 60 * 60 * 24) {
        $h = floor($time/(60*60));
        $str = $h.'小时前 '.$htime;
    }elseif ($time < 60 * 60 * 24 * 3) {
        $d = floor($time/(60*60*24));
        if($d==1){
            $str = '昨天 '.$rtime;
        }else{
            $str = '前天 '.$rtime;
        }
    }else {
        $str = $rtime;
    }
    return $str;
}

/**
 * 概率
 * @param  [string] $chance [1-100,默认为:30%的 例：10%   10]
 * @return [bool]   $result [触发:true  否则:false]
 */
function chance($chance=30){

    if(mt_rand(1,100) <= $chance) {
        $result = TRUE;
    }else{
        $result = FALSE;
    }
    
    return $result;
}

/**
 * 检验ip
 * @param  [string] $ip [ip地址]
 * @return [bool]   $reluse  [true false]
 */
function checkIp($ip){
    $check = "((?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d))))";
    $reluse = preg_match($check,$ip);

    return $reluse;
}

/**
 * 返回该设备存放累积型数据的数据表
 * @param  [string] $guid1 [设备号]
 * @return [string] $his   [表名]
 */
function get_his_data_table($guid1) {

    if(strlen($guid1)<3){
       return '';
    }

    $last_2 = substr( $guid1, -2 );

    $A = base_convert( $last_2[0], 36, 10 );

    $B = base_convert( $last_2[1], 36, 10 );

    $his = 'his_'.floor($A/6).'_'.$B;

    return $his;
}

/**
 * 创建目录创建文件并写入且保存
 * @param  [string] $name    [文件名]
 * @param  [string] $content [内容]
 * @param  [string] $path    [保存路径,默认:upload_file/] 
 * @param  [string] $type    [true：创建文件保存  false:写日志 ]
 */
function saveFile($name,$content,$path="upload_file/",$type=true){

    // 创建文件夹并给777的权限（所有权限）
    if (!file_exists($path)){
        mkdir($path,0777,true);  
    }

    $file = $path.$name;

    if($type){
        $myfile = fopen($file,"w");
    }else{
        $myfile = fopen($file,"a+");
    }
    
    fwrite($myfile, $content);
    fclose($myfile);
}

/**
 * 对象转数组
 * @param [object] $obj [对象]
 * @return [array] $arr [NULL或ARRAY 返回值]
 */
function object_to_array($obj){
    $_arr = is_object($obj) ? get_object_vars($obj) :$obj;
    foreach ($_arr as $key=>$val){
        $val = (is_array($val) || is_object($val)) ? object_to_array($val):$val;
        $arr[$key] = $val;
    }
    return $arr;
}

/**
 * 解析XML
 * @param  [type] $xml [description]
 * @return [type]      [description]
 */
function xml2Array($xml){
    libxml_disable_entity_loader(true);
    $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    return $values;
}